Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: 케이크샵 인증 요청 리스트 API 개발 #183

Merged
merged 16 commits into from
Aug 14, 2024

Conversation

YongsHub
Copy link
Contributor

@YongsHub YongsHub commented Aug 13, 2024

Description

백오피스 API 중, 케이크샵 인증 요청 리스트 목록 조회(아직 처리되지 않은 인증) API 개발

Domain Model Pattern에서 Module간의 응집도가 너무 떨어져서 비즈니스 로직을 재설계하였습니다
- 첫 번째 이슈: 아직 처리되지 않은 상태에 대해서 어떤 값을 가질까?
현재 응집도가 너무 떨어지는 부분은 CakeShop이라는 도메인이 사업자인증이 완료됐는지, 아닌지에 대한 책임을 가지는 부분이 논리적인 오류가 있습니다. 이를 해결하기 위해 BusinessInformation이 책임을 가지도록 재설계 했습니다.

- 두 번째 이슈: 인증이 완료 또는 인증되지 않음 2가지 상태만 가질 수 있을까?
이를 위해 PENDING(보류), APPROVED(인증 완료), REJECTED(거절) 에 대한 3가지 상태로 확장하여 비즈니스 로직을 재설계했습니다.

- 세 번째 이슈: 인증 요청 리스트 목록을 통해 조회 될 데이터가 저장되고 있지 않음
이를 해결하기 위해 BusinessInformation에서 사업자등록증, 신분증 등등 데이터를 저장하도록 재설계 했습니다

캡슐화 문제

  • 인증 처리, 인증 상태를 위해 BusinessInformation이 객체 참조를 하고 있는 User의 상태를 알아야함 + 데이터를 가지고 있는 인증 상태도 확인해야 하는 로직

  • BusinessInformation이 VerificationStatus에 대한 값의 종류와 데이터를 알아야함

  • 인증 처리, 인증 여부를 확인하기 위해 인증 정책에게 메시지를 전송 하도록 리팩토링
    인증 정책의 책임은 유저의 권한과 인증 상태 관리

IMG_0F1AAF220D02-1

해결해야 할 트레이드 오프

  • 패키지 의존성에서 싸이클이 발생 User Module -> VerificationPolicy이 존재하는 Module -> User Module, 해결 필요
    • why? UserModule이 변경되면, VerificationPolicy Module의 내용도 변경되어야 함
  • CakeShop에서 linked_flag를 관리할 필요가 없음 - 응집도가 떨어짐: (특별한 의견 없으면 다음 PR에서 반영할 예정)
  • 의존성 싸이클을 해결하려고 할 때, User Role 중 BUSINESS_OWNER만 없어지면 싸이클이 해결됨. 케이크샵 주인 인증 처리를 하는데 User의 Role이 필요한가? 에 대한 의견이 필요. 케이크 샵 주인이 케이크 샵 정보를 수정할 때도 Business 정보를 통해 권한을 확인해서 관리하면 되지 않을까? 하는 생각

Core Code

etc

Copy link

github-actions bot commented Aug 13, 2024

Test Results

197 tests  +2   197 ✅ +2   16s ⏱️ -1s
 34 suites +1     0 💤 ±0 
 34 files   +1     0 ❌ ±0 

Results for commit 964166a. ± Comparison against base commit f2640f0.

♻️ This comment has been updated with latest results.

Copy link

codecov bot commented Aug 13, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Impacted file tree graph

@@              Coverage Diff              @@
##             develop     #183      +/-   ##
=============================================
+ Coverage      87.92%   88.78%   +0.86%     
- Complexity       315      325      +10     
=============================================
  Files            105      109       +4     
  Lines            952      972      +20     
  Branches          37       37              
=============================================
+ Hits             837      863      +26     
+ Misses            97       92       -5     
+ Partials          18       17       -1     
Files Coverage Δ Complexity Δ
.../com/cakk/api/controller/shop/AdminController.java 100.00% <100.00%> (ø) 3.00 <3.00> (?)
...a/com/cakk/api/controller/shop/ShopController.java 100.00% <ø> (+5.26%) 16.00 <0.00> (-1.00) ⬆️
...k/api/dto/param/operation/OwnerCandidateParam.java 100.00% <100.00%> (ø) 1.00 <1.00> (?)
.../response/shop/CakeShopOwnerCandidateResponse.java 100.00% <100.00%> (ø) 1.00 <1.00> (?)
...com/cakk/api/mapper/BusinessInformationMapper.java 100.00% <100.00%> (ø) 2.00 <2.00> (?)
.../com/cakk/api/mapper/CakeDesignCategoryMapper.java 100.00% <ø> (ø) 2.00 <0.00> (ø)
...in/java/com/cakk/api/service/shop/ShopService.java 98.57% <100.00%> (+0.13%) 20.00 <2.00> (+2.00)

... and 1 file with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update f2640f0...b740880. Read the comment docs.

Copy link
Collaborator

@lcomment lcomment left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

좋은 방식이라고 생각은 듭니다만, VerificationPolicy 객체를 엔티티로 구성하여 저장해놓는게 어떨까요? 인증 요청을 business_information에 저장하는게 조금 부자연스럽네요

Comment on lines +47 to +59
@Column(name = "business_registration_image_url", length = 200)
private String businessRegistrationImageUrl;

@Column(name = "id_card_image_url", length = 200)
private String idCardImageUrl;

@Column(name = "emergency_contact", length = 20)
private String emergencyContact;

@ColumnDefault("0")
@Convert(converter = VerificationStatusConverter.class)
@Column(name = "verification_status", nullable = false)
private VerificationStatus verificationStatus = VerificationStatus.PENDING;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

인증 요청 관련해서 따로 테이블 빼는게 좋지 않을까요?

Comment on lines +7 to +21
@Component
public class DefaultVerificationPolicy implements VerificationPolicy {

@Override
public boolean isCandidate(User user, VerificationStatus verificationStatus) {
return !user.isBusinessOwner() && verificationStatus.isCandidate();
}

@Override
public VerificationStatus approveToBusinessOwner(User user) {
user.upgradedBusinessOwner();
return VerificationStatus.makeApproved();
}
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

단방향을 구성하기 위한 접근은 좋은데, 해당 객체가 아닌 요청 관련해서 따로 도메인을 분리하여 관리하는건 어떤가요?

@YongsHub
Copy link
Contributor Author

좋은 방식이라고 생각은 듭니다만, VerificationPolicy 객체를 엔티티로 구성하여 저장해놓는게 어떨까요? 인증 요청을 business_information에 저장하는게 조금 부자연스럽네요

이 부분에 대해서 저도 고민을 많이 해봤는데, 이것도 하나의 트레이드오프이지 않을까 싶어요

CakeShop과 BusinessInformation에서 정규화 작업은 크게 user, businessNumber 데이터를 분리했다고 생각합니다
근데 "비즈니스 정보" 라는 객체 엔티티의 책임이 딱히 없다고 느껴졌습니다
지금 수행하고있는 응집도 중 하나가 user 정보와 businessNumber인데 user는 객체 참조를 통한 의존성(이는 결국 user가 가지는 책임), businessNumber는 정보 제공 - 이게 곧 응집도가 떨어짐을 의미

그렇기 때문에 "사업자 인증 요청 처리" 라는 작업과 조회에 대한 책임을 부여한 설계로 지금 리팩토링 의도를 담았습니다
인증 관련은 business_information 객체를 통해 응집도 Up

물론 의견을 주신대로 수행하면 데이터베이스 측면에서는 정규화의 이점은 있다고 생각합니다

하지만 VerificationPolicy 객체를 엔티티로 구성하면 백오피스 API이긴 하나, ORM을 쓰면서 지연 로딩에 신경 쓸 부분이 많아지고 트랜잭션의 경계가 총 User, CakeShop, BusinessInformation, VerificationPolicy 4개의 태이블에 대한 Lock을 생각해야 된다고 여겨져서 현재 상황을 유지해보고 명확한 이유가 생겼을 때 분리해보고 싶습니다!

또한 VerificationPolicy를 추상화하여서 현재 DefaultVerificationPolicy 구현체를 활용하고 있는데
Slack으로만 인증 처리를 할 경우에는 다른 구현체 (ex: SlackVerificationPolicy)를 만들어서 대응하고 싶습니다

@YongsHub
Copy link
Contributor Author

좋은 방식이라고 생각은 듭니다만, VerificationPolicy 객체를 엔티티로 구성하여 저장해놓는게 어떨까요? 인증 요청을 business_information에 저장하는게 조금 부자연스럽네요

이 부분에 대해서 저도 고민을 많이 해봤는데, 이것도 하나의 트레이드오프이지 않을까 싶어요

CakeShop과 BusinessInformation에서 정규화 작업은 크게 user, businessNumber 데이터를 분리했다고 생각합니다 근데 "비즈니스 정보" 라는 객체 엔티티의 책임이 딱히 없다고 느껴졌습니다 지금 수행하고있는 응집도 중 하나가 user 정보와 businessNumber인데 user는 객체 참조를 통한 의존성(이는 결국 user가 가지는 책임), businessNumber는 정보 제공 - 이게 곧 응집도가 떨어짐을 의미

그렇기 때문에 "사업자 인증 요청 처리" 라는 작업과 조회에 대한 책임을 부여한 설계로 지금 리팩토링 의도를 담았습니다 인증 관련은 business_information 객체를 통해 응집도 Up

물론 의견을 주신대로 수행하면 데이터베이스 측면에서는 정규화의 이점은 있다고 생각합니다

하지만 VerificationPolicy 객체를 엔티티로 구성하면 백오피스 API이긴 하나, ORM을 쓰면서 지연 로딩에 신경 쓸 부분이 많아지고 트랜잭션의 경계가 총 User, CakeShop, BusinessInformation, VerificationPolicy 4개의 태이블에 대한 Lock을 생각해야 된다고 여겨져서 현재 상황을 유지해보고 명확한 이유가 생겼을 때 분리해보고 싶습니다!

또한 VerificationPolicy를 추상화하여서 현재 DefaultVerificationPolicy 구현체를 활용하고 있는데 Slack으로만 인증 처리를 할 경우에는 다른 구현체 (ex: SlackVerificationPolicy)를 만들어서 대응하고 싶습니다

추가로, 코멘트에 남겨둔 해결해야 할 트레이드 오프 에 대해서도 의견 주시면 감사합니다 - 의견에 따라 로직도 다음PR에서 살짝 변경해야 할 것 같아요

@YongsHub YongsHub added the feature 새로운 기능 개발 label Aug 14, 2024
Comment on lines +47 to +54
@Column(name = "business_registration_image_url", length = 200)
private String businessRegistrationImageUrl;

@Column(name = "id_card_image_url", length = 200)
private String idCardImageUrl;

@Column(name = "emergency_contact", length = 20)
private String emergencyContact;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

새롭게 추가한 컬럼에 대한 초기화는 없나요?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

케이크샵 생성할 때 businessInformation도 같이 생성되어야 해서
user포함 새롭게 추가한 컬럼 nullable에 대해 true로 허용되어야할 것 같습니다

@lcomment
Copy link
Collaborator

PR 트레이드 오프

  • linked_flag
    • 추후에 cake_shop 데이터와 제휴 지점인지에 대한 데이터를 가져올 일이 있을거 같아 역정규화했습니다. 1:1 관계라 제거해도 무방할거 같긴 합니다.
  • user와 business_owner
    • 개발 난이도 때문에 일단 role로 설정해두었습니다. 원하시는 방향으로 리펙토링 해도 상관없습니다.

일단 확인했습니다. 다만, slack api에 문제가 있어서 요청 데이터를 손실한다면 혹시 백업되고 있나요?

@YongsHub
Copy link
Contributor Author

PR 트레이드 오프

  • linked_flag

    • 추후에 cake_shop 데이터와 제휴 지점인지에 대한 데이터를 가져올 일이 있을거 같아 역정규화했습니다. 1:1 관계라 제거해도 무방할거 같긴 합니다.
  • user와 business_owner

    • 개발 난이도 때문에 일단 role로 설정해두었습니다. 원하시는 방향으로 리펙토링 해도 상관없습니다.

일단 확인했습니다. 다만, slack api에 문제가 있어서 요청 데이터를 손실한다면 혹시 백업되고 있나요?

이 부분 백오피스 api 개발 끝나고 PR새롭게 올리겠습니다

@YongsHub YongsHub merged commit d618169 into develop Aug 14, 2024
2 checks passed
@lcomment lcomment deleted the Feature/CAKK-25 branch August 15, 2024 01:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature 새로운 기능 개발
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants